#include "winThreadLogger.h"


Logger::Logger(){
	Output = stdout;
	Filter = INFO;
}

Logger::Logger(FILE *out){
	Output = out;
	Filter = INFO;
}

Logger::Logger(MsgLevel filter){
	Output = stdout;
	Filter = filter;
}

Logger::Logger(FILE *out,MsgLevel filter){
	Output = out;
	Filter = filter;
}

Logger::~Logger(){
}

int Logger::Debug	(char* message, ... ){
	if(Filter >= DEBUG){
		va_list argList;
		va_start(argList,message);
		char tmpMessageBuff[MaxMsgLength+1];
		vsnprintf_s(tmpMessageBuff,MaxMsgLength+1,MaxMsgLength,message,argList);


		buf = & RingBuffer::TryToCreate();
		InterlockedIncrement(& (buf->unprocRec) );
	
		buf->rpsIter %= buf->rpsSize;
		unsigned int l_index =  InterlockedIncrement(&(buf->rpsIter))-1;
		l_index %= buf->rpsSize;
		EnterCriticalSection(&(buf->sharedRps[l_index].columnAccess));	
			(buf->sharedRps[l_index]).msgText = tmpMessageBuff;
			(buf->sharedRps[l_index]).destFile = Output;
			(buf->sharedRps[l_index]).MessageLevel = DEBUG;
			SetEvent(buf->eventWriteToRpsDone[l_index]);
			WaitForSingleObject(buf->eventWriteToFileDone[l_index],INFINITE);
			ResetEvent(buf->eventWriteToFileDone[l_index]);
		LeaveCriticalSection(&(buf->sharedRps[l_index].columnAccess));
	
		InterlockedDecrement(&(buf->unprocRec));
	}
	return 0;
}/*
int Logger::Fatal	(char* message, ... ){
	if(Filter >= FATAL){
		va_list argList;
		va_start(argList,message);
		char tmpMessageBuff[MaxMsgLength+1];
		vsnprintf_s(tmpMessageBuff,MaxMsgLength+1,MaxMsgLength,message,argList);

		InterlockedIncrement(&unprocRec);
	
		rpsIter %= rpsSize;
		unsigned int l_index =  InterlockedIncrement(&rpsIter)-1;
		l_index %= rpsSize;
		EnterCriticalSection(&sharedRps[l_index].columnAccess);	
			sharedRps[l_index].msgText = tmpMessageBuff;
			sharedRps[l_index].destFile = Output;
			sharedRps[l_index].MessageLevel = FATAL;
			SetEvent(eventWriteToRpsDone[l_index]);
			WaitForSingleObject(eventWriteToFileDone[l_index],INFINITE);
			ResetEvent(eventWriteToFileDone[l_index]);
		LeaveCriticalSection(&sharedRps[l_index].columnAccess);
	
		InterlockedDecrement(&unprocRec);
	}
	return 0;
	return 0;
}
int Logger::Error	(char* message, ... ){
if(Filter >= _ERROR){
		va_list argList;
		va_start(argList,message);
		char tmpMessageBuff[MaxMsgLength+1];
		vsnprintf_s(tmpMessageBuff,MaxMsgLength+1,MaxMsgLength,message,argList);

		InterlockedIncrement(&unprocRec);
	
		rpsIter %= rpsSize;
		unsigned int l_index =  InterlockedIncrement(&rpsIter)-1;
		l_index %= rpsSize;
		EnterCriticalSection(&sharedRps[l_index].columnAccess);	
			sharedRps[l_index].msgText = tmpMessageBuff;
			sharedRps[l_index].destFile = Output;
			sharedRps[l_index].MessageLevel = _ERROR;
			SetEvent(eventWriteToRpsDone[l_index]);
			WaitForSingleObject(eventWriteToFileDone[l_index],INFINITE);
			ResetEvent(eventWriteToFileDone[l_index]);
		LeaveCriticalSection(&sharedRps[l_index].columnAccess);
	
		InterlockedDecrement(&unprocRec);
	}
	return 0;
}
int Logger::Warning	(char* message, ... ){
if(Filter >= WARNING){
		va_list argList;
		va_start(argList,message);
		char tmpMessageBuff[MaxMsgLength+1];
		vsnprintf_s(tmpMessageBuff,MaxMsgLength+1,MaxMsgLength,message,argList);

		InterlockedIncrement(&unprocRec);
	
		rpsIter %= rpsSize;
		unsigned int l_index =  InterlockedIncrement(&rpsIter)-1;
		l_index %= rpsSize;
		EnterCriticalSection(&sharedRps[l_index].columnAccess);	
			sharedRps[l_index].msgText = tmpMessageBuff;
			sharedRps[l_index].destFile = Output;
			sharedRps[l_index].MessageLevel = WARNING;
			SetEvent(eventWriteToRpsDone[l_index]);
			WaitForSingleObject(eventWriteToFileDone[l_index],INFINITE);
			ResetEvent(eventWriteToFileDone[l_index]);
		LeaveCriticalSection(&sharedRps[l_index].columnAccess);
	
		InterlockedDecrement(&unprocRec);
	}
	return 0;
}
int Logger::Info	(char* message, ... ){
if(Filter >= INFO){
		va_list argList;
		va_start(argList,message);
		char tmpMessageBuff[MaxMsgLength+1];
		vsnprintf_s(tmpMessageBuff,MaxMsgLength+1,MaxMsgLength,message,argList);

		InterlockedIncrement(&unprocRec);
	
		rpsIter %= rpsSize;
		unsigned int l_index =  InterlockedIncrement(&rpsIter)-1;
		l_index %= rpsSize;
		EnterCriticalSection(&sharedRps[l_index].columnAccess);	
			sharedRps[l_index].msgText = tmpMessageBuff;
			sharedRps[l_index].destFile = Output;
			sharedRps[l_index].MessageLevel = INFO;
			SetEvent(eventWriteToRpsDone[l_index]);
			WaitForSingleObject(eventWriteToFileDone[l_index],INFINITE);
			ResetEvent(eventWriteToFileDone[l_index]);
		LeaveCriticalSection(&sharedRps[l_index].columnAccess);
	
		InterlockedDecrement(&unprocRec);
	}
	return 0;
}
*/
DWORD WINAPI LoggerManager(PVOID pvParam){
	do{
		RingBuffer * tmp_buf;
		tmp_buf = &(RingBuffer::TryToCreate());

		WaitForMultipleObjects(tmp_buf->rpsSize,tmp_buf->eventWriteToRpsDone,FALSE,INFINITE);
		for(int i = 0 ;i<tmp_buf->rpsSize;i++){
			if (WaitForSingleObject(tmp_buf->eventWriteToRpsDone[i],0) != WAIT_TIMEOUT){
				ResetEvent(tmp_buf->eventWriteToRpsDone[i]);
				


				_SYSTEMTIME tmp;
				GetLocalTime(&tmp);
				switch((tmp_buf->sharedRps[i]).MessageLevel){
					case FATAL: 
						fprintf((tmp_buf->sharedRps[i]).destFile,"FATAL"); 
						break;
					case _ERROR: 
						fprintf((tmp_buf->sharedRps[i]).destFile,"ERROR"); 
						break;
					case WARNING: 
						fprintf((tmp_buf->sharedRps[i]).destFile,"WARNING"); 
						break;
					case DEBUG: 
						fprintf((tmp_buf->sharedRps[i]).destFile,"DEBUG"); 
						break;
					case INFO: 
						fprintf((tmp_buf->sharedRps[i]).destFile,"INFO"); 
						break;
				}
				fprintf((tmp_buf->sharedRps[i]).destFile," MESSAGE in [%2.2d.%2.2d.%2.2d] >>> ",tmp.wHour,tmp.wMinute,tmp.wSecond);
				fprintf((tmp_buf->sharedRps[i]).destFile,"%s\n",(tmp_buf->sharedRps[i]).msgText);	
				SetEvent(tmp_buf->eventWriteToFileDone[i]);
			}
		}
	}while(true);
	return 0;
}
